home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / PPPOn 1.0.1 / src / macppp / slhc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-07  |  13.5 KB  |  175 lines  |  [TEXT/CWIE]

  1. /*
  2.  * Routines to compress and uncompress tcp packets (for transmission
  3.  * over low speed serial lines.
  4.  *
  5.  * Copyright (c) 1989 Regents of the University of California.
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms are permitted
  9.  * provided that the above copyright notice and this paragraph are
  10.  * duplicated in all such forms and that any documentation,
  11.  * advertising materials, and other materials related to such
  12.  * distribution and use acknowledge that the software was developed
  13.  * by the University of California, Berkeley.  The name of the
  14.  * University may not be used to endorse or promote products derived
  15.  * from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  *
  20.  *    Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
  21.  *    - Initial distribution.
  22.  *
  23.  * modified for KA9Q Internet Software Package by
  24.  * Katie Stevens (dkstevens@ucdavis.edu)
  25.  * University of California, Davis
  26.  * Computing Services
  27.  *    - 01-31-90    initial adaptation (from 1.19)
  28.  *    PPP.05    02-15-90 [ks]
  29.  *    PPP.08    05-02-90 [ks]    use PPP protocol field to signal compression
  30.  *    PPP.15    09-90     [ks]    improve mbuf handling
  31.  *    PPP.16    11-02     [karn]    substantially rewritten to use NOS facilities
  32.  *
  33.  *    - Feb 1991    Bill_Simpson@um.cc.umich.edu
  34.  *            variable number of conversation slots
  35.  *            allow zero or one slots
  36.  *            separate routines
  37.  *            status display
  38.  *
  39.  *  1992-93  Modifications for MacPPP.
  40.  *                -Larry Blunk, Merit Network, Inc./ University of Michigan
  41.  */
  42.  
  43. #include "ppp.h"
  44. #include "slhc.h"
  45.  
  46. /* Initialize compression data structure
  47.  *    slots must be in range 0 to 255 (zero meaning no compression)
  48.  */
  49. void
  50. slhc_init( LapInfo *lap, short rslots, short tslots )
  51. {
  52.     b_16 i;
  53.     struct cstate *ts;
  54.  
  55.     if ( rslots > 0  &&  rslots <= MAXSLOTS ) {
  56.         lap->comp.rstate = lap->rcvslots;
  57.         lap->comp.rslot_limit = rslots - 1;
  58.     }
  59.  
  60.     if ( tslots > 0  &&  tslots <= MAXSLOTS ) {
  61.         lap->comp.tstate = lap->txslots;
  62.         lap->comp.tslot_limit = tslots - 1;
  63.     }
  64.  
  65.     lap->comp.xmit_oldest = 0;
  66.     lap->comp.xmit_current = lap->comp.recv_current = 255;
  67.  
  68.     if ( tslots > 0 ) {
  69.         ts = lap->comp.tstate;
  70.         for(i = lap->comp.tslot_limit; i > 0; --i){
  71.             ts[i].this = i;
  72.             ts[i].next = &(ts[i - 1]);
  73.         }
  74.         ts[0].next = &(ts[lap->comp.tslot_limit]);
  75.         ts[0].this = 0;
  76.     }
  77. }
  78.  
  79. /* Encode a number */
  80. static b_8 *
  81. encode(b_8 *cp, b_16 n)
  82. {
  83.     if(n >= 256 || n == 0){
  84.         *cp++ = 0;
  85.         *cp++ = n >> 8;
  86.     }
  87.     *cp++ = n;
  88.     return cp;
  89. }
  90.  
  91. /* Decode a number */
  92. static long
  93. decode(struct bufheader *bufptr)
  94. {
  95.     short x;
  96.  
  97.     x = yankbyte(bufptr);
  98.     if (x == 0) {
  99.         return yank16(bufptr);    /* yank16 returns -1 on error */
  100.     } else {
  101.         return (long)x;        /* -1 if error */
  102.     }
  103. }
  104.  
  105. short
  106. slhc_compress(LapInfo *lap, struct bufheader *bufptr, short compress_cid)
  107. {
  108.     struct slcompress *comp = &(lap->comp);
  109.     struct cstate *ocs = &(comp->tstate[comp->xmit_oldest]);
  110.     struct cstate *lcs = ocs;
  111.     struct cstate *cs = lcs->next;
  112.     b_16 hiplen, htcplen, hlen;
  113.     b_16 ipoptlen, tcpoptlen;
  114.     struct tcpheader *oth;
  115.     unsigned long deltaS, deltaA;
  116.     b_16 changes = 0;
  117.     b_8 new_seq[16];
  118.     b_8 *cp = new_seq;
  119.     struct tcpheader th;
  120.     struct ipheader iph;
  121.  
  122.     /* Extract IP header */
  123.     hiplen = getipheader(&iph,bufptr);
  124.     /* Bail if this packet isn't TCP, or is an IP fragment */
  125.     if(iph.protocol != TCP_PROTOCOL || (iph.offset & 0x3fff) != 0 ){
  126.         bufptr->dataptr -= hiplen;
  127.         bufptr->length += hiplen;
  128.         return SL_TYPE_IP;
  129.     }
  130.     /* Extract TCP header */
  131.     htcplen = gettcpheader(&th,bufptr);
  132.     hlen = hiplen + htcplen;
  133.  
  134.     /*  Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or
  135.      *  some other control bit is set).
  136.      */
  137.     if((th.flags & ( TCP_FIN | TCP_SYN | TCP_ACK | TCP_RST )) ^ TCP_ACK ){
  138.         /* TCP connection stuff; send as regular IP */
  139.         bufptr->dataptr -= hlen;
  140.         bufptr->length += hlen;
  141.         return SL_TYPE_IP;
  142.     }
  143.     /*
  144.      * Packet is compressible -- we're going to send either a
  145.      * COMPRESSED_TCP or UNCOMPRESSED_TCP packet.  Either way,
  146.      * we need to locate (or create) the connection state.
  147.      *
  148.      * States are kept in a circularly linked list with
  149.      * xmit_oldest pointing to the end of the list.  The
  150.      * list is kept in lru order by moving a state to the
  151.      * head of the list whenever it is referenced.  Since
  152.      * the list is short and, empirically, the connection
  153.      * we want is almost always near the front, we locate
  154.      * states via linear search.  If we don't find a state
  155.      * for the datagram, the oldest state is (re-)used.
  156.      */
  157.     for ( ; ; ) {
  158.         if( iph.source_addr == cs->cs_ip.source_addr
  159.          && iph.dest_addr == cs->cs_ip.dest_addr
  160.          && th.source_port == cs->cs_tcp.source_port
  161.          && th.dest_port == cs->cs_tcp.dest_port)
  162.             goto found;
  163.  
  164.         /* if current equal oldest, at end of list */
  165.         if ( cs == ocs )
  166.             break;
  167.         lcs = cs;
  168.         cs = cs->next;
  169.     };
  170.     /*
  171.      * Didn't find it -- re-use oldest cstate.  Send an
  172.      * uncompressed packet that tells the other side what
  173.      * connection number we're using for this conversation.
  174.      *
  175.      * Note that since the state list is ci